﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.Contracts;

namespace GBricks.Collections
{
  [ContractClass(typeof(IOrderedDictionaryContract<,>))]
  public interface IOrderedDictionary<TKey, TValue> : IDictionary<TKey, TValue>, IList<KeyValuePair<TKey, TValue>>
  {
    new IReadOnlyList<TKey> Keys { get; }
    new IReadOnlyList<TValue> Values { get; }

    int IndexOf(TKey key);
    void Insert(int index, TKey key, TValue value);
  }

  [ContractClassFor(typeof(IOrderedDictionary<,>))]
  internal abstract class IOrderedDictionaryContract<TKey, TValue> : IOrderedDictionary<TKey, TValue>
  {
    #region IOrderedDictionary<TKey, TValue> Members

    IReadOnlyList<TKey> IOrderedDictionary<TKey, TValue>.Keys {
      get {
        Contract.Ensures(Contract.Result<IReadOnlyList<TKey>>() != null);
        Contract.Ensures(Contract.Result<IReadOnlyList<TKey>>().Count == Count);
        throw new NotImplementedException();
      }
    }

    IReadOnlyList<TValue> IOrderedDictionary<TKey, TValue>.Values {
      get {
        Contract.Ensures(Contract.Result<IReadOnlyList<TValue>>() != null);
        Contract.Ensures(Contract.Result<IReadOnlyList<TValue>>().Count == Count);
        throw new NotImplementedException();
      }
    }

    [Pure]
    int IOrderedDictionary<TKey, TValue>.IndexOf(TKey key) {
      Contract.Ensures(Contract.Result<int>() >= -1);
      Contract.Ensures(Contract.Result<int>() < Count);
      throw new NotImplementedException();
    }

    void IOrderedDictionary<TKey, TValue>.Insert(int index, TKey key, TValue value) {
      Contract.Requires(index >= 0);
      Contract.Requires(index <= Count);
      throw new NotImplementedException();
    }

    #endregion IOrderedDictionary<TKey, TValue> Members

    #region IList<KeyValuePair<TKey, TValue>> Members

    public int IndexOf(KeyValuePair<TKey, TValue> item) {
      throw new NotImplementedException();
    }

    void IList<KeyValuePair<TKey, TValue>>.Insert(int index, KeyValuePair<TKey, TValue> item) {
      throw new NotImplementedException();
    }

    void IList<KeyValuePair<TKey, TValue>>.RemoveAt(int index) {
      throw new NotImplementedException();
    }

    KeyValuePair<TKey, TValue> IList<KeyValuePair<TKey, TValue>>.this[int index] {
      get { return default(KeyValuePair<TKey, TValue>); }
      set { throw new NotImplementedException(); }
    }

    #endregion IList<KeyValuePair<TKey, TValue>> Members

    #region IDictionary<TKey, TValue> Members

    ICollection<TKey> IDictionary<TKey, TValue>.Keys {
      get { throw new NotImplementedException(); }
    }

    ICollection<TValue> IDictionary<TKey, TValue>.Values {
      get { throw new NotImplementedException(); }
    }

    TValue IDictionary<TKey, TValue>.this[TKey key] {
      get { throw new NotImplementedException(); }
      set { throw new NotImplementedException(); }
    }

    void IDictionary<TKey, TValue>.Add(TKey key, TValue value) {
      throw new NotImplementedException();
    }

    public bool ContainsKey(TKey key) {
      throw new NotImplementedException();
    }

    bool IDictionary<TKey, TValue>.Remove(TKey key) {
      throw new NotImplementedException();
    }

    public bool TryGetValue(TKey key, out TValue value) {
      throw new NotImplementedException();
    }

    #endregion IDictionary<TKey, TValue> Members

    #region ICollection<KeyValuePair<TKey,TValue>> Members

    public int Count {
      get { throw new NotImplementedException(); }
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.IsReadOnly {
      get { throw new NotImplementedException(); }
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item) {
      throw new NotImplementedException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.Clear() {
      throw new NotImplementedException();
    }

    public bool Contains(KeyValuePair<TKey, TValue> item) {
      throw new NotImplementedException();
    }

    void ICollection<KeyValuePair<TKey, TValue>>.CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex) {
      throw new NotImplementedException();
    }

    bool ICollection<KeyValuePair<TKey, TValue>>.Remove(KeyValuePair<TKey, TValue> item) {
      throw new NotImplementedException();
    }

    #endregion ICollection<KeyValuePair<TKey, TValue>> Members

    #region IEnumerable<KeyValuePair<TKey, TValue>> Members

    public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() {
      throw new NotImplementedException();
    }

    #endregion IEnumerable<KeyValuePair<TKey, TValue>> Members

    #region IEnumerable Members

    IEnumerator IEnumerable.GetEnumerator() {
      throw new NotImplementedException();
    }

    #endregion IEnumerable Members
  }
}
